home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / os2 / remin301.zip / REMIN300.ZIP / VAR.C < prev    next >
C/C++ Source or Header  |  1992-11-10  |  12KB  |  409 lines

  1. /***************************************************************/
  2. /*                                                             */
  3. /*  VAR.C                                                      */
  4. /*                                                             */
  5. /*  This file contains routines, structures, etc for           */
  6. /*  user- and system-defined variables.                        */
  7. /*                                                             */
  8. /*  This file is part of REMIND.                               */
  9. /*  Copyright (C) 1991 by David F. Skoll.                      */
  10. /*                                                             */
  11. /***************************************************************/
  12.  
  13. #include <stdio.h>
  14. #include "config.h"
  15. #ifdef HAVE_STDLIB_H
  16. #include <stdlib.h>
  17. #endif
  18. #ifdef HAVE_MALLOC_H
  19. #include <malloc.h>
  20. #endif
  21. #include "types.h"
  22. #include "expr.h"
  23. #include "globals.h"
  24. #include "protos.h"
  25. #include "err.h"
  26.  
  27. #define UPPER(c) ( ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 'A' : (c) )
  28.  
  29. /* The variable hash table */
  30. #define VAR_HASH_SIZE 64
  31. static Var *VHashTbl[VAR_HASH_SIZE];
  32.  
  33. /***************************************************************/
  34. /*                                                             */
  35. /*  HashVal                                                    */
  36. /*  Given a string, compute the hash value.                    */
  37. /*                                                             */
  38. /***************************************************************/
  39. #ifdef HAVE_PROTOS
  40. PUBLIC int HashVal(const char *str)
  41. #else
  42. int HashVal(str)
  43. char *str;
  44. #endif
  45. {
  46.    register int i = 0;
  47.    register int j=1;
  48.    register int len=0;
  49.  
  50.    while(*str && len < VAR_NAME_LEN) {
  51.       i += j * UPPER(*str);
  52.       str++;
  53.       len++;
  54.       j = 3-j;
  55.    }
  56.    return i;
  57. }
  58.  
  59. /***************************************************************/
  60. /*                                                             */
  61. /*  FindVar                                                    */
  62. /*  Given a string, find the variable whose name is that       */
  63. /*  string.  If create is 1, create the variable.              */
  64. /*                                                             */
  65. /***************************************************************/
  66. #ifdef HAVE_PROTOS
  67. PUBLIC Var *FindVar(const char *str, int create)
  68. #else
  69. Var *FindVar(str, create)
  70. char *str;
  71. int create;
  72. #endif
  73. {
  74.    register int h;
  75.    register Var *v;
  76.    register Var *prev;
  77.  
  78.    h = HashVal(str) % VAR_HASH_SIZE;
  79.    v = VHashTbl[h];
  80.    prev = NULL;
  81.  
  82.    while(v) {
  83.       if (StrinEq(str, v->name, VAR_NAME_LEN)) return v;
  84.       prev = v;
  85.       v = v-> next;
  86.    }
  87.    if (!create) return v;
  88.  
  89. /* Create the variable */
  90.    v = NEW(Var);
  91.    if (!v) return v;
  92.    v->next = NULL;
  93.    v->v.type = INT_TYPE;
  94.    v->v.v.val = 0;
  95.    v->preserve = 0;
  96.    StrnCpy(v->name, str, VAR_NAME_LEN);
  97.  
  98.    if (prev) prev->next = v; else VHashTbl[h] = v;
  99.    return v;
  100. }
  101.  
  102. /***************************************************************/
  103. /*                                                             */
  104. /*  DeleteVar                                                  */
  105. /*  Given a string, find the variable whose name is that       */
  106. /*  string and delete it.                                      */
  107. /*                                                             */
  108. /***************************************************************/
  109. #ifdef HAVE_PROTOS
  110. PUBLIC int DeleteVar(const char *str)
  111. #else
  112. int DeleteVar(str)
  113. char *str;
  114. #endif
  115. {
  116.    register int h;
  117.    register Var *v;
  118.    register Var *prev;
  119.  
  120.    h = HashVal(str) % VAR_HASH_SIZE;
  121.    v = VHashTbl[h];
  122.    prev = NULL;
  123.  
  124.    while(v) {
  125.       if (StrinEq(str, v->name, VAR_NAME_LEN)) break;
  126.       prev = v;
  127.       v = v-> next;
  128.    }
  129.    if (!v) return E_NOSUCH_VAR;
  130.    DestroyValue(&(v->v));
  131.    if (prev) prev->next = v->next; else VHashTbl[h] = v->next;
  132.    free(v);
  133.    return OK;
  134. }
  135.  
  136. /***************************************************************/
  137. /*                                                             */
  138. /*  SetVar                                                     */
  139. /*                                                             */
  140. /*  Set the indicate variable to the specified value.          */
  141. /*                                                             */
  142. /***************************************************************/
  143. #ifdef HAVE_PROTOS
  144. PUBLIC int SetVar(const char *str, Value *val)
  145. #else
  146. int SetVar(str, val)
  147. char *str;
  148. Value *val;
  149. #endif
  150. {
  151.    Var *v = FindVar(str, 1);
  152.  
  153.    if (!v) return E_NO_MEM;  /* Only way FindVar can fail */
  154.  
  155.    DestroyValue(&(v->v));
  156.    v->v = *val;
  157.    return OK;
  158. }
  159.  
  160. /***************************************************************/
  161. /*                                                             */
  162. /*  GetVarValue                                                */
  163. /*                                                             */
  164. /*  Get a copy of the value of the variable.                   */
  165. /*                                                             */
  166. /***************************************************************/
  167. #ifdef HAVE_PROTOS
  168. PUBLIC int GetVarValue(const char *str, Value *val, Var *locals)
  169. #else
  170. int GetVarValue(str, val, locals)
  171. char *str;
  172. Value *val;
  173. Var *locals;
  174. #endif
  175. {
  176.    Var *v;
  177.  
  178.    /* Try searching local variables first */
  179.    v = locals;
  180.    while (v) {
  181.       if (StrinEq(str, v->name, VAR_NAME_LEN))
  182.      return CopyValue(val, &v->v);
  183.       v = v->next;
  184.    }
  185.  
  186.    v=FindVar(str, 0);
  187.  
  188.    if (!v) {
  189.      Eprint("Undefined variable: %s", str);
  190.      return E_NOSUCH_VAR;
  191.    }
  192.    return CopyValue(val, &v->v);
  193. }
  194.  
  195. /***************************************************************/
  196. /*                                                             */
  197. /*  DoSet - set a variable.                                    */
  198. /*                                                             */
  199. /***************************************************************/
  200. #ifdef HAVE_PROTOS
  201. PUBLIC int DoSet (Parser *p)
  202. #else
  203. int DoSet (p)
  204. Parser *p;
  205. #endif
  206. {
  207.    Value v;
  208.    int r;
  209.  
  210.    r = ParseIdentifier(p, TokBuffer);
  211.    if (r) return r;
  212.  
  213.    r = EvaluateExpr(p, &v);
  214.    if (r) return r;
  215.  
  216.    r = SetVar(TokBuffer, &v);
  217.  
  218.    return r;
  219. }
  220.  
  221. /***************************************************************/
  222. /*                                                             */
  223. /*  DoUnset - delete a bunch of variables.                     */
  224. /*                                                             */
  225. /***************************************************************/
  226. #ifdef HAVE_PROTOS
  227. PUBLIC int DoUnset (Parser *p)
  228. #else
  229. int DoUnset (p)
  230. Parser *p;
  231. #endif
  232. {
  233.    int r;
  234.  
  235.    r = ParseToken(p, TokBuffer);
  236.    if (r) return r;
  237.    if (!*TokBuffer) return E_EOLN;
  238.  
  239.    (void) DeleteVar(TokBuffer);  /* Ignore error - nosuchvar */
  240.  
  241. /* Keep going... */
  242.    while(1) {
  243.       r = ParseToken(p, TokBuffer);
  244.       if (r) return r;
  245.       if (!*TokBuffer) return OK;
  246.       (void) DeleteVar(TokBuffer);
  247.    }
  248. }
  249.  
  250. /***************************************************************/
  251. /*                                                             */
  252. /*  DoDump                                                     */
  253. /*                                                             */
  254. /*  Command file command to dump variable table.               */
  255. /*                                                             */
  256. /***************************************************************/
  257. #ifdef HAVE_PROTOS
  258. PUBLIC int DoDump(ParsePtr p)
  259. #else
  260. int DoDump(p)
  261. ParsePtr p;
  262. #endif
  263. {
  264.    int r;
  265.    Var *v;
  266.  
  267.    r = ParseToken(p, TokBuffer);
  268.    if (r) return r;
  269.    if (!*TokBuffer || *TokBuffer == '#' || *TokBuffer == ';') {
  270.       DumpVarTable();
  271.       return OK;
  272.    }
  273.    fprintf(ErrFp, "%*s  %s\n\n", VAR_NAME_LEN, "Variable", "Value");
  274.    while(1) {
  275.       v = FindVar(TokBuffer, 0);
  276.       TokBuffer[VAR_NAME_LEN] = 0;
  277.       if (!v) fprintf(ErrFp, "%*s  *UNDEFINED*\n", VAR_NAME_LEN, TokBuffer);
  278.       else {
  279.          fprintf(ErrFp, "%*s  ", VAR_NAME_LEN, v->name);
  280.          PrintValue(&(v->v), ErrFp);
  281.      fprintf(ErrFp, "\n");
  282.       }
  283.       r = ParseToken(p, TokBuffer);
  284.       if (r) return r;
  285.       if (!*TokBuffer || *TokBuffer == '#' || *TokBuffer == ';') return OK;
  286.    }
  287. }
  288.  
  289. /***************************************************************/
  290. /*                                                             */
  291. /*  DumpVarTable                                               */
  292. /*                                                             */
  293. /*  Dump the variable table to stderr.                         */
  294. /*                                                             */
  295. /***************************************************************/
  296. #ifdef HAVE_PROTOS
  297. PUBLIC void DumpVarTable(void)
  298. #else
  299. void DumpVarTable()
  300. #endif
  301. {
  302.    register Var *v;
  303.    register int i;
  304.  
  305.    fprintf(ErrFp, "%*s  %s\n\n", VAR_NAME_LEN, "Variable", "Value");
  306.  
  307.    for (i=0; i<VAR_HASH_SIZE; i++) {
  308.       v = VHashTbl[i];
  309.       while(v) {
  310.          fprintf(ErrFp, "%*s  ", VAR_NAME_LEN, v->name);
  311.          PrintValue(&(v->v), ErrFp);
  312.          fprintf(ErrFp, "\n");
  313.      v = v->next;
  314.       }
  315.    }
  316. }
  317.  
  318. /***************************************************************/
  319. /*                                                             */
  320. /*  DestroyVars                                                */
  321. /*                                                             */
  322. /*  Free all the memory used by variables, but don't delete    */
  323. /*  preserved variables.                                       */
  324. /*                                                             */
  325. /***************************************************************/
  326. #ifdef HAVE_PROTOS
  327. PUBLIC void DestroyVars(void)
  328. #else
  329. void DestroyVars()
  330. #endif
  331. {
  332.    int i;
  333.    Var *v, *next, *prev;
  334.  
  335.    for (i=0; i<VAR_HASH_SIZE; i++) {
  336.       v = VHashTbl[i];
  337.       VHashTbl[i] = NULL;
  338.       prev = NULL;
  339.       while(v) {
  340.          if (!v->preserve) {
  341.             DestroyValue(&(v->v));
  342.            next = v->next;
  343.         free(v);
  344.      } else {
  345.         if (prev) prev->next = v;
  346.         else VHashTbl[i] = v;
  347.         prev = v;
  348.         next = v->next;
  349.         v->next = NULL;
  350.          }
  351.      v = next;
  352.       }
  353.    }
  354. }
  355.  
  356. /***************************************************************/
  357. /*                                                             */
  358. /*  PreserveVar                                                */
  359. /*                                                             */
  360. /*  Given the name of a variable, "preserve" it.               */
  361. /*                                                             */
  362. /***************************************************************/
  363. #ifdef HAVE_PROTOS
  364. PUBLIC int PreserveVar(char *name)
  365. #else
  366. int PreserveVar(name)
  367. char *name;
  368. #endif
  369. {
  370.    Var *v;
  371.  
  372.    v = FindVar(name, 1);
  373.    if (!v) return E_NO_MEM;
  374.    v->preserve = 1;
  375.    return OK;
  376. }
  377.  
  378. /***************************************************************/
  379. /*                                                             */
  380. /*  DoPreserve - delete a bunch of variables.                  */
  381. /*                                                             */
  382. /***************************************************************/
  383. #ifdef HAVE_PROTOS
  384. PUBLIC int DoPreserve (Parser *p)
  385. #else
  386. int DoPreserve (p)
  387. Parser *p;
  388. #endif
  389. {
  390.    int r;
  391.  
  392.    r = ParseToken(p, TokBuffer);
  393.    if (r) return r;
  394.    if (!*TokBuffer) return E_EOLN;
  395.  
  396.    r = PreserveVar(TokBuffer);
  397.    if (r) return r;
  398.  
  399. /* Keep going... */
  400.    while(1) {
  401.       r = ParseToken(p, TokBuffer);
  402.       if (r) return r;
  403.       if (!*TokBuffer) return OK;
  404.       r = PreserveVar(TokBuffer);
  405.       if (r) return r;
  406.    }
  407. }
  408.  
  409.